home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 013 / chkdir.arc / CHKDIR.C next >
Encoding:
C/C++ Source or Header  |  1985-03-29  |  11.8 KB  |  358 lines

  1. /*  CHKDIR - Report on directory status.
  2.  
  3.     BY:  Thom Henderson
  4.  
  5.     DESCRIPTION:
  6.      Prints a report similar to that produced by CHKDSK, but
  7.      pertaining to the current or named directory. Disk allocation
  8.      errors are NOT (repeat, NOT) fixed.
  9.  
  10.     INSTRUCTIONS:
  11.      Invoke this program with a statement of the form:
  12.  
  13.           CHKDIR [d:][path]
  14.  
  15.     LANGUAGE:
  16.      Computer Innovations C86
  17.  
  18.     SPECIAL NOTES:
  19.      This program should be compiled and linked
  20.      using the "small model".
  21. */
  22. #include <stdio.h>
  23.  
  24. struct fds                   /* file data structure */
  25. {   char dummy[21];               /* reserved for dos */
  26.     unsigned char att;               /* returned attribute */
  27.     unsigned time;
  28.     unsigned date;
  29.     long size;                   /* size of file */
  30.     unsigned char name[13];           /* string containing the filename */
  31.     int first;                   /* true during first search */
  32. };
  33.  
  34. char srchname[200] = 0;            /* search template */
  35. long room;                   /* total room on disk */
  36. long roomleft;                   /* room left on disk */
  37.  
  38. /*  file grouping parameters:
  39.  
  40.     files are grouped in the following categories:
  41.  
  42.     0     anything in a subdirectory
  43.     1     all files of whatever kind
  44.     2     all user files
  45.     3     all read only user files
  46.     4     all hidden or system files
  47.     5     all normal subdirectories
  48.     6     all hidden or system subdirectories
  49.  
  50.     Each group contains the following parts:
  51.  
  52.     0     everything
  53.     1     everything not backed up
  54.     2     everything backed up
  55. */
  56.  
  57. #define ngrps 7                /* number of file groups */
  58.  
  59. long size[ngrps][3] = 0;           /* bytes in each group */
  60. int num[ngrps][3] = 0;               /* files in each group */
  61.  
  62. /* option flags */
  63.  
  64. int subsrch = 0;               /* true if looking in subdirs */
  65. int subsep = 1;                /* true if subdir files not added */
  66. int reptype = 0;               /* which part to report */
  67.  
  68. main(an,arg)                   /* report on directory status */
  69. int an;                    /* number of arguments */
  70. char *arg[];                   /* pointers to same */
  71. {
  72.     int a;                   /* argument index */
  73.     char *ap;                   /* argument pointer */
  74.  
  75.     for(a=1; a<an; a++)            /* scan each arg */
  76.     {     ap = arg[a];               /* get a pointer to it */
  77.  
  78.          if(*ap=='-' || *ap=='/')      /* if an option marker */
  79.      {    while(*++ap)           /* then scan the marks */
  80.           {    switch(tolower(*ap))/* and act on them */
  81.            {
  82.                    case 'a':
  83.             subsep = 0;
  84.                    case 's':
  85.             subsrch = 1;
  86.             break;
  87.                    case 'c':
  88.             reptype = 1;
  89.             break;
  90.                    case 'b':
  91.             reptype = 2;
  92.             break;
  93.            default:
  94.             usage();
  95.            }
  96.           }
  97.      }
  98.      else                   /* else assume it is a path */
  99.      {    if(*srchname)           /* watch out for multiples */
  100.            usage();
  101.           strcpy(srchname,ap);     /* store name in search template */
  102.      }
  103.     }
  104.  
  105.     collect();                   /* collect the data */
  106.     volume();                   /* report on volume */
  107.     disk();                   /* report on disk */
  108.     memory();                   /* report on memory */
  109.  
  110.     return 0;                   /* no error we know of */
  111. }
  112.  
  113. usage()                    /* an error in usage */
  114. {   printf("CHKDIR, Version 1.43, created on 10/17/84 at 10:31:29\n");
  115.     printf("(C)COPYRIGHT 1984 by System Enhancement Associates; may be\n");
  116.     printf("    freely distributed in its original, unmodified form.\n\n");
  117.     printf("If you like this program and find it useful,\n");
  118.     printf("please send five dollars to:\n\n");
  119.     printf("   System Enhancement Associates\n");
  120.     printf("   12 Franklin Avenue\n");
  121.     printf("   Clifton, NJ  07011\n");
  122.     printf("   (201) 694-4710\n\n");
  123.     printf("usage: chkdir [-sacb] [d:][path]\n");
  124.     printf("          -s = search subdirectories\n");
  125.     printf("          -a = add subdirectory files to report\n");
  126.     printf("          -c = report only on files not backed up\n");
  127.     printf("          -b = report only on files backed up\n");
  128.     printf("          -h = print this list\n");
  129.     exit(1);
  130. }
  131.  
  132. volume()                   /* report on volume */
  133. {
  134.     struct fds vd;               /* volume data structure */
  135.  
  136.     if(volname(&vd))               /* if we have a volume */
  137.     {     printf("Volume %s, created ",vd.name);
  138.      pdate(vd.date); ptime(vd.time);
  139.      printf("\n");
  140.     }
  141. }
  142.  
  143. disk()                       /* report on disk */
  144. {
  145.     static char *type[] =           /* report types */
  146.     {     "all files",
  147.      "files which are not backed up",
  148.      "files which have been backed up"
  149.     };
  150.     static char *name[] =           /* group names */
  151.     {     "files in subdirectories",
  152.      "files",
  153.      "user files",
  154.      "read only user files",
  155.      "hidden or system files",
  156.      "subdirectories",
  157.      "hidden or system subdirectories"
  158.     };
  159.     int g;                   /* group index */
  160.     char *dir;                   /* pointer to directory name */
  161.     char *gcdir();               /* gets name of current directory */
  162.  
  163.     dir = *srchname ? srchname : gcdir("");
  164.     printf("Report on %s for %s\n\n",type[reptype],dir);
  165.  
  166.     printf("%9ld bytes total disk space\n",room);
  167.     if(num[0][reptype])
  168.      printf("%9ld bytes in %d files in %d directories\n",
  169.           size[0][reptype],num[0][reptype],num[5][0]);
  170.     for(g=1; g<ngrps; g++)
  171.      if(num[g][reptype])
  172.           printf("%9ld bytes in %d %s\n",
  173.            size[g][reptype],num[g][reptype],name[g]);
  174.     printf("%9ld bytes available on disk\n\n",roomleft);
  175. }
  176.  
  177. collect()                   /* collect our data */
  178. {
  179.     struct {int ax,bx,cx,dx,si,di,ds,es;} reg;
  180.  
  181.     reg.ax = (0x36 << 8);           /* get disk free space */
  182.     if(srchname[1]==':')               /* if path includes a drive */
  183.          reg.dx = tolower(srchname[0])-'a'+1;
  184.     else reg.dx = 0;               /* else default drive */
  185.     sysint21(®,®);           /* DOS call */
  186.  
  187.     if(reg.ax==0xffff)
  188.      abort("%c: is an invalid drive",srchname[0]);
  189.  
  190.     room = (long)reg.dx * (long)reg.cx * (long)reg.ax;
  191.     roomleft = (long)reg.bx * (long)reg.cx * (long)reg.ax;
  192.  
  193.     fcollect(srchname,0);           /* collect the file data */
  194. }
  195.  
  196. fcollect(path,sub)               /* collect data on directory */
  197. char *path;                   /* name of directory */
  198. int sub;                   /* true if in a subdirectory */
  199. {
  200.     char pbuf[200];               /* modified path buffer */
  201.     char sbuf[200];               /* subdirectory path buffer */
  202.     struct fds fd;               /* file data structure */
  203.     int g;                   /* group index */
  204.     char *makepath();               /* path name fixer */
  205.  
  206.     makepath(pbuf,path,"*.*");           /* make a search template */
  207.     fd.first = 1;               /* note start of a search */
  208.  
  209.     while(filedir(&fd,pbuf))           /* while we have files */
  210.     {     if(fd.att&0x10)           /* if a subdirectory */
  211.          {    if(*fd.name=='.')        /* if a phony directory */
  212.            continue;           /* then do not add it in */
  213.           if(subsrch)           /* if we are searching subs */
  214.            fcollect(makepath(sbuf,path,fd.name),subsep);
  215.      }
  216.  
  217.      if(sub)               /* if in a subdirectory */
  218.           addfile(&fd,0);           /* then add to subdir file group */
  219.      else                   /* else add in wherever needed */
  220.      {    addfile(&fd,1);           /* add to total */
  221.  
  222.           if(fd.att&0x10)           /* subdirectory */
  223.           {    if(fd.att&0x06)     /* hidden or system */
  224.             addfile(&fd,6);
  225.            else addfile(&fd,5);
  226.           }
  227.  
  228.           else if(fd.att&0x06)     /* hidden or system file */
  229.            addfile(&fd,4);
  230.  
  231.           else if(fd.att&0x01)     /* read only file */
  232.            addfile(&fd,3);
  233.  
  234.           else addfile(&fd,2);     /* else normal user file */
  235.      }
  236.     }
  237. }
  238.  
  239. char *makepath(buf,path,add)           /* make a path name or template */
  240. char *buf;                   /* storage for result */
  241. char *path;                   /* starting path name */
  242. char *add;                   /* text to add on the end */
  243. {
  244.     extern char *makefnam();           /* filename fixer (optional) */
  245.     char *b = buf;               /* string copy pointer */
  246.     char c = 0;                /* one char of copy */
  247.  
  248.     while(*path)               /* copy over the path */
  249.      *b++ = c = *path++;
  250.  
  251.     if(c)                   /* if any path at all */
  252.          if(c!='\\' && c!=':')         /* if not path and not just disk */
  253.               *b++ = '\\';             /* then add a backslash */
  254.  
  255.     while(*b++ = *add++);           /* tack on the added part */
  256.     return makefnam(buf,"",buf);       /* pass back fixed up name */
  257. }
  258.  
  259. addfile(fd,grp)                /* add a file to a group */
  260. struct fds *fd;                /* pointer to file data */
  261. int grp;                   /* group to add file to */
  262. {
  263.     num[grp][0] += 1;               /* add to total */
  264.     size[grp][0] += fd->size;
  265.     if(fd->att&0x20)               /* if file is not backed up */
  266.     {     num[grp][1] += 1;           /* then add to changed total */
  267.      size[grp][1] += fd->size;
  268.     }
  269.     else                   /* else add to backed up total */
  270.     {     num[grp][2] += 1;
  271.      size[grp][2] += fd->size;
  272.     }
  273. }
  274.  
  275. memory()                   /* report on memory */
  276. {
  277.     struct {int scs,sss,sds,ses;} seg;
  278.     struct {int ax,bx,cx,dx,si,di,ds,es;} reg;
  279.     long core;                   /* total system memory */
  280.     long coreused;               /* system memory in use */
  281.  
  282.     segread(&seg);               /* read our segment registers */
  283.     coreused = (long)seg.scs * 16;     /* see how much is in use */
  284.     sysint(0x12,®,®);           /* memory size determination */
  285.     core = (long)reg.ax * 1024;        /* set total system memory */
  286.  
  287.     printf("%9ld bytes total memory\n",core);
  288.     printf("%9ld bytes in use\n",coreused);
  289.     printf("%9ld bytes free\n",core-coreused);
  290. }
  291.  
  292. int filedir(fd,name)               /* get a directory entry */
  293. struct fds *fd;                /* data storage area */
  294. char *name;                   /* filename template */
  295. {
  296.     struct {int ax,bx,cx,dx,si,di,ds,es;} reg;
  297.  
  298.     segread(®.si);               /* set the segments */
  299.     bdos(0x1a,fd);               /* set the transfer address */
  300.  
  301.     reg.dx = name;               /* point to search template */
  302.     reg.cx = 0x16;               /* include special files */
  303.     if(fd->first)               /* if this is our first call */
  304.      reg.ax = (0x4e << 8);           /* then find first */
  305.     else reg.ax = (0x4f << 8);           /* else find next */
  306.     fd->first = 0;               /* next will not be first */
  307.     return !(sysint21(®,®)&1);   /* return true if it works */
  308. }
  309.  
  310. int volname(fd)                /* get the volume entry */
  311. struct fds *fd;                /* data storage area */
  312. {
  313.     struct {int ax,bx,cx,dx,si,di,ds,es;} reg;
  314.     char vnb[100];               /* volume name template buffer */
  315.  
  316.     segread(®.si);               /* set the segments */
  317.     bdos(0x1a,fd);               /* set the transfer address */
  318.     makefnam("\\*.*",srchname,vnb);    /* set proper drive in template */
  319.  
  320.     reg.dx = vnb;               /* point to volume template */
  321.     reg.cx = 0x08;               /* volume label wanted */
  322.     reg.ax = (0x4e << 8);           /* find first (only?) */
  323.     return !(sysint21(®,®)&1);   /* return true if it works */
  324. }
  325.  
  326. pdate(date)                   /* print a date */
  327. struct                       /* structure of date word */
  328. {   unsigned day : 5;               /* day */
  329.     unsigned month : 4;            /* month */
  330.     unsigned year : 7;               /* year since 1980 */
  331. }   date;                   /* date to print */
  332. {
  333.     static char *mname[] =           /* list of month names */
  334.     {     "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  335.      "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  336.     };
  337.  
  338.     printf("%s %2d, %04d ",mname[date.month-1],date.day,date.year+1980);
  339. }
  340.  
  341. ptime(time)                   /* print a time */
  342. struct                       /* structure of time word */
  343. {   unsigned sec : 5;               /* second pair */
  344.     unsigned minute : 6;           /* minute */
  345.     unsigned hour : 5;               /* hour */
  346. }   time;                   /* time to print */
  347. {
  348.     int hh = time.hour;            /* fudged time */
  349.     char ap = hh<12 ? 'a' : 'p';       /* am/pm marker */
  350.  
  351.     if(hh>12)                   /* if afternoon */
  352.      hh -= 12;               /* then convert to civilian */
  353.     if(hh==0)                   /* if in the wee hours */
  354.      hh = 12;               /* then give as midnight */
  355.  
  356.     printf("%2d:%02d%c ",hh,time.minute,ap);
  357. }
  358.